package service

import (
	"errors"
	"framework-server/global"
	"framework-server/model"
	"framework-server/model/request"
	"framework-server/utils"
	uuid "github.com/satori/go.uuid"
	"gorm.io/gorm"
	"strings"
)

//@author: [piexlmax](https://github.com/piexlmax)
//@function: Register
//@description: 用户注册
//@param: u model.SysUser
//@return: err error, userInter model.SysUser

func Register(u model.SysUser) (err error, userInter model.SysUser) {
	var user model.SysUser
	if !errors.Is(global.GVA_DB.Where("username = ?", u.Username).First(&user).Error, gorm.ErrRecordNotFound) { // 判断用户名是否注册
		return errors.New("用户名已注册"), userInter
	}
	// 否则 附加uuid 密码md5简单加密 注册
	u.Password = utils.MD5V([]byte(u.Password))
	u.UUID = uuid.NewV4()
	err = global.GVA_DB.Create(&u).Error
	return err, u
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: Login
//@description: 用户登录
//@param: u *model.SysUser
//@return: err error, userInter *model.SysUser

func Login(u *model.SysUser) (err error, userInter *model.SysUser, perm map[string]interface{}) {
	perm = make(map[string]interface{})
	//admin用户走密码认证，其他用户走ldap认证
	var user model.SysUser
	if u.Username == "admin" {
		u.Password = utils.MD5V([]byte(u.Password))
		err = global.GVA_DB.Where("username = ? AND password = ?", u.Username, u.Password).Preload("Authority").First(&user).Error
		if err != nil {
			return
		}
	} else {
		ls, err := utils.NewLdapService()
		if err != nil {
			return err, &user, perm
		}
		valid, ldapUserInfo := ls.Check(u.Username, u.Password)
		if !valid {
			err = errors.New("密码不正确")
			// return err, &user, perm
		}
		var user_id uint
		if errors.Is(global.GVA_DB.Where("username = ?", u.Username).First(&user).Error, gorm.ErrRecordNotFound) {
			uuser := model.SysUser{
				Username:    u.Username,
				NickName:    ldapUserInfo["name"],
				Mobile:      ldapUserInfo["mobile"],
				UUID:        uuid.NewV4(),
				AuthorityId: "9528",
			}

			err := global.GVA_DB.Create(&uuser).Error
			if err != nil {
				return err, nil, perm
			}
			user_id = uuser.ID
		} else {
			user.NickName = ldapUserInfo["name"]
			user.Mobile = ldapUserInfo["mobile"]
			err := global.GVA_DB.Where("username = ? ", u.Username).Updates(&user).Error
			if err != nil {
				return err, nil, perm
			}
			user_id = user.ID
		}
		//获取用户的角色信息
		err = global.GVA_DB.Where("id=?", user_id).Preload("Authority").First(&user).Error
		if err != nil {
			return err, &user, perm
		}
	}
	// 获取用户的按钮权限和obj权限
	var authority model.SysAuthority
	var buttonMap = make(map[string]string)
	var objMap = make(map[string][]string)
	var sysAuthorityObjs []model.SysAuthorityObj
	err = global.GVA_DB.Where("authority_id=?", user.AuthorityId).Preload("SysButtons").First(&authority).Error
	if err != nil {
		return err, &user, perm
	}
	for _, v := range authority.SysButtons {
		buttonMap[v.Name] = v.Cname
	}
	err = global.GVA_DB.Where("authority_id = ?", user.AuthorityId).Find(&sysAuthorityObjs).Error
	if err != nil {
		return err, &user, perm
	}
	for _, v := range sysAuthorityObjs {
		objMap[v.Key] = strings.Split(v.Value, ";")
	}
	perm["objMap"] = objMap
	perm["buttonMap"] = buttonMap
	return nil, &user, perm
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: ChangePassword
//@description: 修改用户密码
//@param: u *model.SysUser, newPassword string
//@return: err error, userInter *model.SysUser

func ChangePassword(u *model.SysUser, newPassword string) (err error, userInter *model.SysUser) {
	var user model.SysUser
	u.Password = utils.MD5V([]byte(u.Password))
	err = global.GVA_DB.Where("username = ? AND password = ?", u.Username, u.Password).First(&user).Update("password", utils.MD5V([]byte(newPassword))).Error
	return err, u
}

// @author: [piexlmax](https://github.com/piexlmax)
// @function: GetUserInfoList
// @description: 分页获取数据
// @param: info request.PageInfo
// @return: err error, list interface{}, total int64
// 如果是管理员则获取所有，否则获取子角色用户及普通用户
func GetUserInfoList(info request.SysUserSearch, user model.SysUser) (err error, list interface{}, total int64) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	//db := global.GVA_DB.Model(&model.SysUser{})
	db := global.GVA_DB.Table("sys_users")
	db = db.Joins("join sys_authorities on sys_authorities.authority_id = sys_users.authority_id and sys_authorities.deleted_at is null and sys_users.deleted_at is null")

	var userList []model.SysUser
	if info.Username != "" {
		db = db.Where("username like ?", info.Username)
	}
	if info.NickName != "" {
		db = db.Where("nick_name like ?", info.NickName)
	}
	if info.AuthorityId != "" {
		db = db.Where("sys_users.authority_id = ?", info.AuthorityId)
	}
	if user.AuthorityId != "888" {
		if user.Authority.ParentId == "888" { //管理员子角色
			db = db.Where("username != ?", "admin")
		} else {
			//获取子角色下的用户
			db = db.Where("sys_authorities.parent_id = ? or sys_authorities.authority_id = 9528", user.AuthorityId)
		}
	}
	err = db.Count(&total).Error
	err = db.Limit(limit).Offset(offset).Preload("Authority").Find(&userList).Error
	return err, userList, total
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: SetUserAuthority
//@description: 设置一个用户的权限
//@param: uuid uuid.UUID, authorityId string
//@return: err error

func SetUserAuthority(uuid uuid.UUID, authorityId string) (err error) {
	err = global.GVA_DB.Where("uuid = ?", uuid).First(&model.SysUser{}).Update("authority_id", authorityId).Error
	return err
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: DeleteUser
//@description: 删除用户
//@param: id float64
//@return: err error

func DeleteUser(id float64) (err error) {
	var user model.SysUser
	err = global.GVA_DB.Where("id = ?", id).Delete(&user).Error
	return err
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: SetUserInfo
//@description: 设置用户信息
//@param: reqUser model.SysUser
//@return: err error, user model.SysUser

func SetUserInfo(reqUser model.SysUser) (err error, user model.SysUser) {
	err = global.GVA_DB.Updates(&reqUser).Error
	return err, reqUser
}

//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: FindUserById
//@description: 通过id获取用户信息
//@param: id int
//@return: err error, user *model.SysUser

func FindUserById(id int) (err error, user *model.SysUser) {
	var u model.SysUser
	err = global.GVA_DB.Where("`id` = ?", id).First(&u).Error
	return err, &u
}

//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: FindUserByUuid
//@description: 通过uuid获取用户信息
//@param: uuid string
//@return: err error, user *model.SysUser

func FindUserByUuid(uuid string) (err error, user *model.SysUser) {
	var u model.SysUser
	if err = global.GVA_DB.Where("`uuid` = ?", uuid).First(&u).Error; err != nil {
		return errors.New("用户不存在"), &u
	}
	return nil, &u
}

func GetUserInfoListWithoutPage() (err error, list interface{}) {
	db := global.GVA_DB.Model(&model.SysUser{})
	var userList []model.SysUser

	err = db.Find(&userList).Error
	return err, userList
}
